/**
 * 文档管理模块 - 附件列表组件
 * Phase 3: MinIO 前端集成
 * 
 * 功能：
 * - 文件列表展示（图片预览、文档图标）
 * - 文件信息显示（名称、大小、上传时间）
 * - 文件操作（下载、删除、复制链接）
 * - 加载状态和空状态处理
 */

import React, { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { Badge } from '@/components/ui/badge';
import {
  Download,
  Trash2,
  Copy,
  FileText,
  Image as ImageIcon,
  File,
  CheckCircle2,
  AlertCircle,
  Loader2
} from 'lucide-react';
import { fileService } from '@/lib/api/services/file-service';
import { cn } from '@/lib/utils';
import { toast } from 'sonner';

/**
 * 格式化文件大小
 * @param {number} size - 文件大小（字节）
 * @returns {string} 格式化后的文件大小
 */
const formatFileSize = (size = 0) => {
  if (!size) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB'];
  let index = 0;
  let value = size;
  while (value >= 1024 && index < units.length - 1) {
    value /= 1024;
    index++;
  }
  return `${value.toFixed(value >= 10 ? 0 : 1)} ${units[index]}`;
};

/**
 * 格式化日期时间
 * @param {string} dateString - 日期字符串
 * @returns {string} 格式化后的日期时间
 */
const formatDateTime = (dateString) => {
  if (!dateString) return '-';
  return new Date(dateString).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  });
};

/**
 * 获取文件图标
 * @param {string} mimeType - MIME类型
 * @param {string} fileType - 文件类型
 * @returns {React.ReactNode} 图标组件
 */
const getFileIcon = (mimeType, fileType) => {
  if (fileType === 'image' || mimeType?.startsWith('image/')) {
    return <ImageIcon className="size-4 text-blue-500" />;
  }
  if (mimeType?.includes('pdf')) {
    return <FileText className="size-4 text-red-500" />;
  }
  if (mimeType?.includes('word') || mimeType?.includes('document')) {
    return <FileText className="size-4 text-blue-600" />;
  }
  if (mimeType?.includes('excel') || mimeType?.includes('spreadsheet')) {
    return <FileText className="size-4 text-green-600" />;
  }
  return <File className="size-4 text-gray-500" />;
};

/**
 * 附件列表组件
 * @param {object} props
 * @param {Array} props.files - 文件列表
 * @param {string|number} props.documentId - 关联文档ID（可选）
 * @param {Function} props.onDelete - 删除回调 (fileId) => void
 * @param {Function} props.onDownload - 下载回调 (file) => void
 * @param {Function} props.onRefresh - 刷新回调
 * @param {boolean} props.isLoading - 加载状态
 * @param {boolean} props.allowEdit - 是否允许编辑（上传、删除），默认 false（只读模式）
 * @param {string} props.markdownContent - Markdown 内容（用于检测孤立文件），可选
 * @param {string} props.className - 自定义样式类
 */
const FileList = ({
  files = [],
  documentId = null,
  onDelete,
  onDownload,
  onRefresh,
  isLoading = false,
  allowEdit = false,
  markdownContent = '',
  className = ''
}) => {
  const [deletingIds, setDeletingIds] = useState(new Set());
  const [downloadingIds, setDownloadingIds] = useState(new Set());

  /**
   * 检测文件是否为孤立文件（未在 Markdown 内容中被引用）
   * 只检查 upload_source='editor' 的文件
   * @param {object} file - 文件对象
   * @returns {boolean} 是否为孤立文件
   */
  const isOrphanFile = (file) => {
    try {
      // 只检查 editor 来源的文件
      if (!file || file.uploadSource !== 'editor') {
        return false;
      }

      // 如果没有 Markdown 内容，无法判断
      if (!markdownContent || typeof markdownContent !== 'string') {
        return false;
      }

      // 获取文件 URL（优先使用 fileUrl，其次使用 thumbnailUrl）
      const fileUrl = file.fileUrl || file.thumbnailUrl;
      if (!fileUrl || typeof fileUrl !== 'string') {
        return false;
      }

      // 提取文件路径（从完整 URL 中提取路径部分）
      // 例如：http://192.168.1.86:9000/doc-images/2024/11/uuid.jpg
      // 提取：2024/11/uuid.jpg 或 uuid.jpg
      try {
        const urlObj = new URL(fileUrl);
        const pathParts = urlObj.pathname.split('/').filter(Boolean);
        if (pathParts.length === 0) {
          return false;
        }
        // 获取最后几段路径（通常是 year/month/uuid.ext）
        const pathToCheck = pathParts.slice(-3).join('/'); // 例如：2024/11/uuid.jpg
        const fileNameOnly = pathParts[pathParts.length - 1]; // 例如：uuid.jpg
        
        // 检查 Markdown 内容中是否包含此路径或文件名
        // 匹配模式：![alt](url) 中的 url 部分
        const hasPath = markdownContent.includes(pathToCheck);
        const hasFileName = markdownContent.includes(fileNameOnly);
        
        // 如果都不包含，说明是孤立文件
        return !hasPath && !hasFileName;
      } catch (urlError) {
        // URL 解析失败，尝试简单字符串匹配
        const urlPath = fileUrl.split('/').slice(-3).join('/');
        return urlPath && !markdownContent.includes(urlPath);
      }
    } catch (error) {
      // 任何错误都返回 false，不标记为孤立文件
      console.warn('检测孤立文件时出错:', error, file);
      return false;
    }
  };

  /**
   * 处理文件下载
   */
  const handleDownload = async (file) => {
    if (downloadingIds.has(file.id)) return;

    setDownloadingIds(prev => new Set(prev).add(file.id));

    try {
      // 如果是公开文件，直接使用 fileUrl
      if (file.accessPolicy === 'public' && file.fileUrl) {
        window.open(file.fileUrl, '_blank');
        toast.success('文件已在新窗口打开');
      } else {
        // 私有文件需要获取下载链接
        const downloadInfo = await fileService.getDownloadUrl(file.id);
        if (downloadInfo?.downloadUrl) {
          window.open(downloadInfo.downloadUrl, '_blank');
          toast.success('文件已在新窗口打开');
        } else {
          throw new Error('获取下载链接失败');
        }
      }

      onDownload && onDownload(file);
    } catch (error) {
      console.error('下载失败:', error);
      toast.error(error.message || '下载失败');
    } finally {
      setDownloadingIds(prev => {
        const next = new Set(prev);
        next.delete(file.id);
        return next;
      });
    }
  };

  /**
   * 处理文件删除
   */
  const handleDelete = async (file) => {
    if (deletingIds.has(file.id)) return;

    // 检查上传来源和是否孤立文件
    const isOrphan = isOrphanFile(file);
    
    if (file.uploadSource === 'editor') {
      if (isOrphan) {
        // 孤立文件：已从 Markdown 中删除，可以安全删除
        if (!confirm(`此文件在 Markdown 内容中已不再使用。\n\n确定要删除文件 "${file.fileName}" 吗？此操作不可恢复。`)) {
          return;
        }
      } else {
        // 非孤立文件：仍在 Markdown 中使用，删除会导致链接失效
        const confirmMessage = `警告：此文件正在 Markdown 内容中使用。\n\n删除此文件会导致 Markdown 内容中的图片链接失效。\n\n确定要继续删除吗？`;
        if (!confirm(confirmMessage)) {
          return;
        }
      }
    } else {
      // 非 editor 来源的文件，正常删除
      if (!confirm(`确定要删除文件 "${file.fileName}" 吗？此操作不可恢复。`)) {
        return;
      }
    }

    setDeletingIds(prev => new Set(prev).add(file.id));

    try {
      await fileService.delete(file.id);
      toast.success('文件已删除');
      onDelete && onDelete(file.id);
      onRefresh && onRefresh();
    } catch (error) {
      console.error('删除失败:', error);
      toast.error(error.message || '删除失败');
    } finally {
      setDeletingIds(prev => {
        const next = new Set(prev);
        next.delete(file.id);
        return next;
      });
    }
  };

  /**
   * 复制文件链接
   */
  const handleCopyLink = async (file) => {
    const url = file.fileUrl || file.thumbnailUrl;
    if (!url) {
      toast.error('文件链接不可用');
      return;
    }

    try {
      await navigator.clipboard.writeText(url);
      toast.success('文件链接已复制到剪贴板');
    } catch (error) {
      console.error('复制失败:', error);
      toast.error(error.message || '复制失败');
    }
  };

  // 加载状态
  if (isLoading) {
    return (
      <div className={cn('space-y-2', className)}>
        {[1, 2, 3].map(i => (
          <Card key={i}>
            <CardContent className="p-2.5">
              <div className="flex items-center gap-3">
                <Skeleton className="h-10 w-10 rounded" />
                <div className="flex-1 space-y-1.5">
                  <Skeleton className="h-3.5 w-48" />
                  <Skeleton className="h-2.5 w-32" />
                </div>
                <Skeleton className="h-7 w-20" />
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    );
  }

  // 空状态
  if (!files || files.length === 0) {
    return (
      <Card className={cn(className)}>
        <CardContent className="p-8 text-center">
          <File className="size-12 mx-auto text-muted-foreground mb-4" />
          <p className="text-muted-foreground">暂无附件</p>
        </CardContent>
      </Card>
    );
  }

  return (
    <div className={cn('space-y-2', className)}>
      {files.map((file) => {
        // 安全检查：确保 file 对象存在且有效
        if (!file || !file.id) {
          console.warn('FileList: 发现无效的文件对象', file);
          return null;
        }

        const isImage = file.fileType === 'image' || file.mimeType?.startsWith('image/');
        const isDeleting = deletingIds.has(file.id);
        const isDownloading = downloadingIds.has(file.id);

        return (
          <Card key={file.id} className="hover:bg-muted/50 transition-colors">
            <CardContent className="p-2.5">
              <div className="flex items-center gap-3">
                {/* 文件预览/图标 */}
                <div className="flex-shrink-0">
                  {isImage && file.thumbnailUrl ? (
                    <img
                      src={file.thumbnailUrl}
                      alt={file.fileName}
                      className="h-10 w-10 object-cover rounded border cursor-pointer"
                      onClick={() => window.open(file.fileUrl || file.thumbnailUrl, '_blank')}
                    />
                  ) : (
                    <div className="h-10 w-10 flex items-center justify-center rounded border bg-muted">
                      {file ? getFileIcon(file.mimeType, file.fileType) : <File className="size-4 text-gray-500" />}
                    </div>
                  )}
                </div>

                {/* 文件信息 */}
                <div className="flex-1 min-w-0">
                  <div className="flex items-center justify-between gap-2">
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <h4 className="font-medium text-xs truncate" title={file?.fileName || '未知文件'}>
                          {file?.fileName || '未知文件'}
                        </h4>
                        {/* 孤立文件警告标识 */}
                        {(() => {
                          try {
                            return isOrphanFile(file) ? (
                              <Badge variant="warning" appearance="light" size="sm" className="text-[10px] px-1.5 py-0">
                                ⚠️ 未使用
                              </Badge>
                            ) : null;
                          } catch (error) {
                            console.warn('FileList: 检测孤立文件时出错', error);
                            return null;
                          }
                        })()}
                      </div>
                      <div className="flex items-center gap-2 mt-0.5 text-[11px] text-muted-foreground">
                        <span>{formatFileSize(file?.fileSize || 0)}</span>
                        <span>·</span>
                        <span>{formatDateTime(file?.createdAt || file?.created_at)}</span>
                        {file?.fileType && (
                          <>
                            <span>·</span>
                            <span className="capitalize">{file.fileType}</span>
                          </>
                        )}
                        {(() => {
                          try {
                            return isOrphanFile(file) ? (
                              <>
                                <span>·</span>
                                <span className="text-amber-600 dark:text-amber-400">
                                  Markdown 中已删除
                                </span>
                              </>
                            ) : null;
                          } catch (error) {
                            console.warn('FileList: 检测孤立文件时出错', error);
                            return null;
                          }
                        })()}
                      </div>
                    </div>
                  </div>
                </div>

                {/* 操作按钮 */}
                <div className="flex items-center gap-0.5 flex-shrink-0">
                  {/* 下载按钮 */}
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => handleDownload(file)}
                    disabled={isDownloading}
                    title="下载文件"
                    className="h-7 w-7 p-0"
                  >
                    {isDownloading ? (
                      <Loader2 className="size-3.5 animate-spin" />
                    ) : (
                      <Download className="size-3.5" />
                    )}
                  </Button>

                  {/* 复制链接按钮 */}
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => handleCopyLink(file)}
                    title="复制链接"
                    className="h-7 w-7 p-0"
                  >
                    <Copy className="size-3.5" />
                  </Button>

                  {/* 删除按钮（仅在允许编辑时显示） */}
                  {allowEdit && (
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => handleDelete(file)}
                      disabled={isDeleting}
                      title={
                        isOrphanFile(file)
                          ? '删除文件（此文件在 Markdown 中已不再使用）'
                          : file.uploadSource === 'editor'
                          ? '删除文件（警告：此文件在 Markdown 中使用）'
                          : '删除文件'
                      }
                      className={cn(
                        "h-7 w-7 p-0 text-destructive hover:text-destructive",
                        file.uploadSource === 'editor' && !isOrphanFile(file) && "opacity-80"
                      )}
                    >
                      {isDeleting ? (
                        <Loader2 className="size-3.5 animate-spin" />
                      ) : (
                        <Trash2 className="size-3.5" />
                      )}
                    </Button>
                  )}
                </div>
              </div>
            </CardContent>
          </Card>
        );
      })}
    </div>
  );
};

export default FileList;

